<template>
  <div class="login-container">
    <div class="login-form">
      <h2 class="login-title">虾塘养殖管理系统</h2>

      <!-- 二维码登录区域 -->
      <div class="qr-login-section" v-if="showQRLogin">
        <div class="qr-code-container">
          <canvas id="qrcodeCanvas" v-if="qrString"></canvas>
          <div v-else class="qr-loading">
            <el-icon class="is-loading"><Loading /></el-icon>
            <span>生成二维码中...</span>
          </div>
          <div class="qr-refresh-btn" @click="handleManualRefresh">
            <el-icon><Refresh /></el-icon>
          </div>
        </div>

        <div class="qr-status" :class="statusClass">{{ statusText }}</div>

        <div class="demo-info">
          <p>5分钟后自动刷新二维码</p>
        </div>

        <div class="login-options">
          <el-button link @click="switchToPhoneLogin">使用手机号登录</el-button>
        </div>
      </div>

      <!-- 手机号登录区域 -->
      <div class="phone-login-section" v-else>
        <el-form :model="form" :rules="rules" ref="loginFormRef">
          <el-form-item prop="phone">
            <el-input
              v-model="form.phone"
              placeholder="请输入手机号"
              :prefix-icon="User"
              size="large"
              maxlength="11"
            ></el-input>
          </el-form-item>
          <el-form-item>
            <el-button
              type="primary"
              style="width: 100%"
              :loading="loading"
              @click="handlePhoneLogin"
              size="large"
              >登录</el-button
            >
          </el-form-item>
        </el-form>

        <div class="login-options">
          <el-button link @click="switchToQRLogin">使用微信扫码登录</el-button>
        </div>

        <div class="login-tips">
          <p>请输入您的手机号进行登录</p>
          <p>系统将根据手机号自动识别用户角色</p>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, reactive, onMounted, onUnmounted } from "vue";
import { useRouter } from "vue-router";
import {
  ElMessage,
  ElForm,
  ElFormItem,
  ElInput,
  ElButton,
  ElIcon,
} from "element-plus";
import { Loading, User, Refresh } from "@element-plus/icons-vue";
import QRCode from "qrcode";

import {
  confirmLogin,
  requestGenerateQR,
  requestRefreshQR,
  phoneLogin,
} from "@/api/login";
import { getWebsocket } from "@/utils/websocketUtil";
import { saveTokenInfo } from "@/utils/auth";

const router = useRouter();
const loginFormRef = ref(null);
const loading = ref(false);

// WebSocket相关
const wsInstance = ref(null);
const isConnecting = ref(false);
const reconnectTimer = ref(null);

// 二维码登录相关
const showQRLogin = ref(true);
const qrString = ref("");
const statusText = ref("请使用微信小程序扫描二维码登录");
const statusClass = ref("status-waiting");
const qrRefreshTimer = ref(null);

const form = reactive({
  phone: "",
});

// 手机号验证规则
const validatePhone = (rule, value, callback) => {
  if (!value) {
    callback(new Error("请输入手机号"));
  } else if (!/^1[3-9]\d{9}$/.test(value)) {
    callback(new Error("请输入正确的手机号格式"));
  } else {
    callback();
  }
};

const rules = reactive({
  phone: [
    { required: true, message: "请输入手机号", trigger: "blur" },
    { validator: validatePhone, trigger: "blur" },
  ],
});

// 保存用户信息到本地存储
const saveUserInfo = (userData) => {
  const userInfo = {
    name: userData.name || "用户",
    avatar: userData.avatar || null,
    role: userData.role || "user",
    phone: form.phone,
    loginTime: new Date().toISOString(),
  };
  localStorage.setItem("userInfo", JSON.stringify(userInfo));
};

// 生成二维码
const generateQRCode = async () => {
  // 先清理现有资源
  closeWebSocket();

  if (qrRefreshTimer.value) {
    clearTimeout(qrRefreshTimer.value);
    qrRefreshTimer.value = null;
  }

  try {
    statusClass.value = "status-waiting";
    statusText.value = "正在生成二维码...";

    const response = await requestGenerateQR();

    // 解析接口响应
    const { code, data: qrData, message } = response;
    console.log("生成二维码响应:", response);
    if (code !== 0) throw new Error(message || "获取二维码失败");
    if (!qrData) throw new Error("接口未返回有效二维码字符串");

    // 保存二维码字符串并绘制
    qrString.value = qrData;
    statusText.value = "请使用微信小程序扫描二维码登录";
    await drawQRCode();

    // 建立WebSocket连接
    connectWebSocket();

    // 设置自动刷新定时器
    qrRefreshTimer.value = setTimeout(() => {
      console.log("二维码已过期，自动刷新");
      refreshQRCode();
    }, 300000);
  } catch (error) {
    console.error("获取二维码异常:", error);
    ElMessage.error(error.message || "二维码获取失败，请重试");
    statusText.value = error.message || "二维码获取失败，请重试";
    statusClass.value = "status-error";
  }
};

// 刷新二维码
const refreshQRCode = async () => {
  // 刷新前先关闭所有连接和定时器
  closeWebSocket();

  if (qrRefreshTimer.value) {
    clearTimeout(qrRefreshTimer.value);
    qrRefreshTimer.value = null;
  }

  try {
    statusClass.value = "status-waiting";
    statusText.value = "正在刷新二维码...";
    const response = await requestRefreshQR(qrString.value);

    // 解析刷新响应
    const { code, data: newQrData, message } = response;
    console.log("刷新二维码响应:", response);
    if (code !== 0) throw new Error(message || "刷新二维码失败");
    if (!newQrData) throw new Error("接口未返回新二维码字符串");

    // 更新二维码并重置状态
    qrString.value = newQrData;
    statusText.value = "二维码已刷新，请重新扫描";
    await drawQRCode();

    // 重置5分钟自动刷新定时器
    qrRefreshTimer.value = setTimeout(() => {
      console.log("二维码已过期，自动刷新");
      refreshQRCode();
    }, 300000);

    // 建立新的WebSocket连接
    connectWebSocket();
    ElMessage.success("二维码已刷新");
  } catch (error) {
    console.error("刷新二维码异常:", error);
    ElMessage.error(error.message || "二维码刷新失败，请重试");
    statusText.value = error.message || "二维码刷新失败，请重试";
    statusClass.value = "status-error";
  }
};

const handleManualRefresh = () => {
  refreshQRCode();
};

// 绘制二维码
const drawQRCode = () => {
  return new Promise((resolve) => {
    setTimeout(() => {
      const canvas = document.getElementById("qrcodeCanvas");
      if (canvas && qrString.value) {
        QRCode.toCanvas(
          canvas,
          qrString.value,
          {
            width: 200,
            margin: 2,
            color: {
              dark: "#1b9a7c",
              light: "#ffffff",
            },
          },
          (error) => {
            if (error) {
              console.error("绘制二维码失败:", error);
              drawFallbackQRCode();
            }
            resolve();
          }
        );
      }
    }, 100);
  });
};

// 备选二维码绘制方案
const drawFallbackQRCode = () => {
  const canvas = document.getElementById("qrcodeCanvas");
  if (!canvas) return;

  const ctx = canvas.getContext("2d");
  const size = 200;

  canvas.width = size;
  canvas.height = size;

  ctx.clearRect(0, 0, size, size);
  ctx.fillStyle = "#ffffff";
  ctx.fillRect(0, 0, size, size);
  ctx.fillStyle = "#1b9a7c";
  ctx.font = "16px Arial";
  ctx.fillText("QR Code", size / 2 - 30, size / 2);
  ctx.fillText(qrString.value.substring(0, 8), size / 2 - 40, size / 2 + 20);
};

const connectWebSocket = () => {
  // 先关闭现有连接
  closeWebSocket();

  if (!qrString.value) {
    console.error("没有二维码字符串，无法建立WebSocket连接");
    return;
  }

  isConnecting.value = true;

  try {
    // 调用封装的getWebsocket函数创建连接
    const ws = getWebsocket(qrString.value);
    if (!ws) {
      throw new Error("WebSocket连接创建失败");
    }

    wsInstance.value = ws;

    // 连接成功
    ws.onopen = () => {
      console.log("WebSocket连接成功，等待扫码通知...");
      isConnecting.value = false;
      statusText.value = "请使用微信小程序扫描二维码登录";
      statusClass.value = "status-waiting";
    };

    // 接收后端消息
    ws.onmessage = async (event) => {
      const message = event.data.trim();
      console.log("收到WebSocket消息:", message);

      // 处理登录成功消息
      if (message === qrString.value) {
        statusText.value = "验证成功，正在确认登录...";
        statusClass.value = "status-success";

        try {
          // 调用确认登录接口
          const response = await confirmLogin(message);

          const { code, data, message: respMsg } = response;
          if (code === 0 && data?.accessToken) {
            // 保存token信息
            saveTokenInfo(data);

            // 处理登录成功逻辑
            statusText.value = "登录成功，正在跳转...";
            closeWebSocket();
            console.log("webSocket关闭成功");
            handleLoginSuccess(data); // 传递用户信息
            console.log("登录跳转成功");
          } else {
            throw new Error(respMsg || "登录确认失败");
          }
        } catch (error) {
          console.error("登录确认失败:", error);
          statusText.value = error.message || "登录确认失败，请重试";
          statusClass.value = "status-error";
          // 失败后刷新二维码
          setTimeout(() => {
            closeWebSocket();
            refreshQRCode();
          }, 2000);
        }
      } else {
        // 处理其他消息
        statusText.value = "二维码验证失败，请重新扫描";
        statusClass.value = "status-error";
        // 失败后刷新二维码
        setTimeout(() => {
          closeWebSocket();
          refreshQRCode();
        }, 2000);
      }
    };

    // 连接错误
    ws.onerror = (error) => {
      console.error("WebSocket错误:", error);
      isConnecting.value = false;
      statusText.value = "连接异常，请刷新页面";
      statusClass.value = "status-error";

      // 错误时尝试重连，但不要立即重连
      if (statusClass.value !== "status-success") {
        reconnectTimer.value = setTimeout(() => {
          if (qrString.value && !isConnecting.value) {
            console.log("尝试重新连接WebSocket...");
            connectWebSocket();
          }
        }, 5000); // 5秒后重连
      }
    };

    // 连接关闭
    ws.onclose = (event) => {
      console.log("WebSocket连接关闭:", event.code, event.reason);
      isConnecting.value = false;

      // 只有非正常关闭且不是登录成功状态时才重连
      if (event.code !== 1000 && statusClass.value !== "status-success") {
        reconnectTimer.value = setTimeout(() => {
          if (qrString.value && !isConnecting.value) {
            console.log("WebSocket断开，尝试重连...");
            connectWebSocket();
          }
        }, 3000);
      }
    };
  } catch (error) {
    console.error("创建WebSocket连接异常:", error);
    isConnecting.value = false;
    statusText.value = "连接失败，请重试";
    statusClass.value = "status-error";
  }
};

const closeWebSocket = () => {
  if (wsInstance.value) {
    // 先移除所有事件监听器
    wsInstance.value.onopen = null;
    wsInstance.value.onmessage = null;
    wsInstance.value.onerror = null;
    wsInstance.value.onclose = null;

    // 检查连接状态，只在连接打开时关闭
    if (wsInstance.value.readyState === WebSocket.OPEN) {
      wsInstance.value.close(1000, "正常关闭"); // 使用标准关闭码
    }

    wsInstance.value = null;
  }

  if (reconnectTimer.value) {
    clearTimeout(reconnectTimer.value);
    reconnectTimer.value = null;
  }

  isConnecting.value = false;
};

// 登录成功跳转
const handleLoginSuccess = (data) => {
  statusText.value = "登录成功，正在跳转...";
  statusClass.value = "status-success";

  // 保存用户信息
  saveUserInfo({
    name: data.userName || "微信用户",
    role: data.role || "user",
    openId: data.openIdWeb,
  });

  ElMessage.success("登录成功！");

  // 先关闭连接再跳转，增加短暂延迟确保关闭完成
  closeWebSocket();
  setTimeout(() => {
    router.push("/dashboard");
  }, 500);
};

// 切换登录方式
const switchToPhoneLogin = () => {
  showQRLogin.value = false;
};

const switchToQRLogin = () => {
  showQRLogin.value = true;
  generateQRCode();
};

// 手机号登录
const handlePhoneLogin = async () => {
  if (!loginFormRef.value) return;

  loginFormRef.value.validate(async (valid) => {
    if (valid) {
      loading.value = true;

      try {
        const response = await phoneLogin(form.phone);

        const { code, data, message } = response;

        if (code === 0 && data?.accessToken) {
          // 保存token信息
          saveTokenInfo(data);

          // 保存用户信息
          saveUserInfo({
            name: `用户${form.phone.slice(-4)}`, // 使用手机号后4位作为用户名
            role: data.role || "user",
            phone: form.phone,
          });

          ElMessage.success("登录成功！");
          router.push("/dashboard");
        } else {
          throw new Error(message || "登录失败");
        }
      } catch (error) {
        console.error("手机号登录失败:", error);
        ElMessage.error(error.message || "登录失败，请重试");
      } finally {
        loading.value = false;
      }
    } else {
      ElMessage.warning("请填写正确的手机号");
    }
  });
};

onMounted(() => {
  generateQRCode();
});

onUnmounted(() => {
  // 清理所有定时器和连接
  closeWebSocket();

  if (qrRefreshTimer.value) {
    clearTimeout(qrRefreshTimer.value);
    qrRefreshTimer.value = null;
  }
});
</script>

<style scoped>
.login-container {
  display: flex;
  justify-content: center;
  align-items: center;
  width: 100%;
  min-height: 100vh;
  padding: 20px;
  background: linear-gradient(135deg, #1b9a7c 0%, #2daf8b 100%);
}

.login-form {
  width: 100%;
  max-width: 400px;
  padding: 40px;
  background-color: #fff;
  border-radius: 12px;
  box-shadow: 0 10px 40px rgba(0, 0, 0, 0.1);
}

.login-title {
  text-align: center;
  color: #1b9a7c;
  margin-bottom: 30px;
  font-size: 24px;
  font-weight: bold;
}

.qr-login-section {
  text-align: center;
}

.qr-refresh-btn {
  color: #666;
  position: absolute;
  bottom: 10px;
  right: 10px;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: all 0.3s;
}

.qr-refresh-btn:hover {
  background: #fff;
  transform: rotate(180deg);
}

.qr-code-container {
  position: relative;
}

.qr-code-container {
  margin: 20px 0;
  padding: 20px;
  background: #f8f9fa;
  border-radius: 8px;
  min-height: 240px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.qr-loading {
  display: flex;
  flex-direction: column;
  align-items: center;
  color: #666;
  gap: 10px;
}

.qr-status {
  margin: 15px 0;
  font-size: 14px;
  min-height: 20px;
  padding: 8px 12px;
  border-radius: 6px;
}

.status-waiting {
  color: #666;
  background: #f5f5f5;
}

.status-success {
  color: #67c23a;
  background: #f0f9eb;
}

.status-error {
  color: #f56c6c;
  background: #fef0f0;
}

.login-options {
  text-align: center;
  margin-top: 20px;
}

.phone-login-section {
  text-align: center;
}

.login-tips {
  margin-top: 20px;
  font-size: 12px;
  color: #909399;
  text-align: center;
  line-height: 1.5;
}

.demo-info {
  background: #f0f9eb;
  border: 1px solid #e1f3d8;
  border-radius: 4px;
  padding: 12px;
  margin-top: 20px;
  font-size: 12px;
  color: #67c23a;
}
</style>
